import random
import math

class BinomialEdgeGen(object):


    def __init__(self, edgeProb):
        '''
        Constructor
        '''
        self.EdgeProb = edgeProb
        
    def Apply(self, network):
        if self.EdgeProb < 0 or self.EdgeProb > 1:
            print("error - EdgeProb must be from 0 to 1")
            pass
        elif self.EdgeProb == 0:
            pass
        elif self.EdgeProb == 1:
            for sourceAgent in network.agentList:
                for targetAgent in network.agentList:
                    if sourceAgent != targetAgent:
                        network.graph.add_edge(sourceAgent, targetAgent)
        else:            
            #This algorithm is taken from networkX's fast_gnp_random_graph() function.
            random.seed()
            if self.EdgeProb != 0:
                v = 0
                w = -1
                n = len(network.agentList)
                lp = math.log(1.0 - self.EdgeProb)  
        
                while v < n:
                    lr = math.log(1.0 - random.random())
                    w = w + 1 + int(lr/lp)
                    if v == w: # avoid self loops
                        w = w + 1
                    while  w >= n and v < n:
                        w = w - n
                        v = v + 1
                        if v == w: # avoid self loops
                            w = w + 1
                    if v < n:
                        network.graph.add_edge(network.agentList[v], network.agentList[w])
